Add --lib to init/new. Add status message for completed creation
authorJonathan Turner <jturner@mozilla.com>
Fri, 29 Jul 2016 19:52:33 +0000 (12:52 -0700)
committerJonathan Turner <jturner@mozilla.com>
Fri, 29 Jul 2016 19:52:33 +0000 (12:52 -0700)
src/bin/init.rs
src/bin/new.rs
src/cargo/ops/cargo_new.rs
tests/cargotest/support/mod.rs
tests/init.rs
tests/new.rs
tests/workspaces.rs

index a779ec7e148b7d95ce40c1202e2beee4cb8b4d84..237d7663fb4fce7540d117d31bc0a0d8be5416df 100644 (file)
@@ -9,6 +9,7 @@ pub struct Options {
     flag_quiet: Option<bool>,
     flag_color: Option<String>,
     flag_bin: bool,
+    flag_lib: bool,
     arg_path: Option<String>,
     flag_name: Option<String>,
     flag_vcs: Option<ops::VersionControl>,
@@ -28,7 +29,8 @@ Options:
     --vcs VCS           Initialize a new repository for the given version
                         control system (git or hg) or do not initialize any version
                         control at all (none) overriding a global configuration.
-    --bin               Use a binary instead of a library template
+    --bin               Use a binary (application) template
+    --lib               Use a library template
     --name NAME         Set the resulting package name
     -v, --verbose ...   Use verbose output
     -q, --quiet         No output printed to stdout
@@ -45,16 +47,22 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
                           options.flag_frozen,
                           options.flag_locked));
 
-    let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options;
+    let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
 
-    let opts = ops::NewOptions {
-        version_control: flag_vcs,
-        bin: flag_bin,
-        path: &arg_path.unwrap_or(format!(".")),
-        name: flag_name.as_ref().map(|s| s.as_ref()),
-    };
+    let tmp = &arg_path.unwrap_or(format!("."));
+    let opts = ops::NewOptions::new(flag_vcs,
+                                     flag_bin,
+                                     flag_lib,
+                                     tmp,
+                                     flag_name.as_ref().map(|s| s.as_ref()));
 
+    let opts_lib = opts.lib;
     try!(ops::init(opts, config));
+
+    try!(config.shell().status("Created", format!("{} project",
+                                                   if opts_lib { "library" }
+                                                   else {"binary (application)"})));
+
     Ok(None)
 }
 
index e90194f1d66a3bb11a469847e099b58158e2ff9d..1d7770d7a06f41e9061c09cfb6860c20cebf2d27 100644 (file)
@@ -9,6 +9,7 @@ pub struct Options {
     flag_quiet: Option<bool>,
     flag_color: Option<String>,
     flag_bin: bool,
+    flag_lib: bool,
     arg_path: String,
     flag_name: Option<String>,
     flag_vcs: Option<ops::VersionControl>,
@@ -28,7 +29,8 @@ Options:
     --vcs VCS           Initialize a new repository for the given version
                         control system (git or hg) or do not initialize any version
                         control at all (none) overriding a global configuration.
-    --bin               Use a binary instead of a library template
+    --bin               Use a binary (application) template
+    --lib               Use a library template
     --name NAME         Set the resulting package name
     -v, --verbose ...   Use verbose output
     -q, --quiet         No output printed to stdout
@@ -45,16 +47,22 @@ pub fn execute(options: Options, config: &Config) -> CliResult<Option<()>> {
                           options.flag_frozen,
                           options.flag_locked));
 
-    let Options { flag_bin, arg_path, flag_name, flag_vcs, .. } = options;
+    let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
 
-    let opts = ops::NewOptions {
-        version_control: flag_vcs,
-        bin: flag_bin,
-        path: &arg_path,
-        name: flag_name.as_ref().map(|s| s.as_ref()),
-    };
+    let opts = ops::NewOptions::new(flag_vcs,
+                                    flag_bin,
+                                    flag_lib,
+                                    &arg_path,
+                                    flag_name.as_ref().map(|s| s.as_ref()));
 
+    let opts_lib = opts.lib;
     try!(ops::new(opts, config));
+
+    try!(config.shell().status("Created", format!("{} `{}` project",
+                                                   if opts_lib { "library" }
+                                                   else {"binary (application)"},
+                                                   arg_path)));
+
     Ok(None)
 }
 
index 856f06ba048636bf6897cebe63d789f631d33fe5..fe00a74d9891c0218178be3421c68073257d6d05 100644 (file)
@@ -21,6 +21,7 @@ pub enum VersionControl { Git, Hg, NoVcs }
 pub struct NewOptions<'a> {
     pub version_control: Option<VersionControl>,
     pub bin: bool,
+    pub lib: bool,
     pub path: &'a str,
     pub name: Option<&'a str>,
 }
@@ -53,6 +54,31 @@ impl Decodable for VersionControl {
     }
 }
 
+impl<'a> NewOptions<'a> {
+    pub fn new(version_control: Option<VersionControl>,
+           bin: bool,
+           lib: bool,
+           path: &'a str,
+           name: Option<&'a str>) -> NewOptions<'a> {
+
+        // default to lib
+        let is_lib = if !bin {
+            true
+        }
+        else {
+            lib
+        };
+
+        NewOptions {
+            version_control: version_control,
+            bin: bin,
+            lib: is_lib,
+            path: path,
+            name: name,
+        }
+    }
+}
+
 struct CargoNewConfig {
     name: Option<String>,
     email: Option<String>,
@@ -235,6 +261,10 @@ pub fn new(opts: NewOptions, config: &Config) -> CargoResult<()> {
               path.display())
     }
 
+    if opts.lib && opts.bin {
+        bail!("can't specify both lib and binary outputs");
+    }
+
     let name = try!(get_name(&path, &opts, config));
     try!(check_name(name));
 
@@ -260,6 +290,10 @@ pub fn init(opts: NewOptions, config: &Config) -> CargoResult<()> {
         bail!("`cargo init` cannot be run on existing Cargo projects")
     }
 
+    if opts.lib && opts.bin {
+        bail!("can't specify both lib and binary outputs");
+    }
+
     let name = try!(get_name(&path, &opts, config));
     try!(check_name(name));
 
index d21bb01b0f71b1424a3b41a98fca26d34f08e5d7..f493faef6adf5cbffede90a1beaf150227e458df 100644 (file)
@@ -636,6 +636,7 @@ fn substitute_macros(input: &str) -> String {
     let macros = [
         ("[RUNNING]",     "     Running"),
         ("[COMPILING]",   "   Compiling"),
+        ("[CREATED]",     "     Created"),
         ("[FINISHED]",    "    Finished"),
         ("[ERROR]",       "error:"),
         ("[WARNING]",     "warning:"),
index 0e180bb45de3ee58d3b1ef8c58c30fb908ee06f1..f63b249d92905a4d7da9743f014a68b379e8b9c8 100644 (file)
@@ -20,9 +20,11 @@ fn cargo_process(s: &str) -> ProcessBuilder {
 
 #[test]
 fn simple_lib() {
-    assert_that(cargo_process("init").arg("--vcs").arg("none")
+    assert_that(cargo_process("init").arg("--lib").arg("--vcs").arg("none")
                                     .env("USER", "foo"),
-                execs().with_status(0));
+                execs().with_status(0).with_stderr("\
+[CREATED] library project
+"));
 
     assert_that(&paths::root().join("Cargo.toml"), existing_file());
     assert_that(&paths::root().join("src/lib.rs"), existing_file());
@@ -38,7 +40,9 @@ fn simple_bin() {
     fs::create_dir(&path).unwrap();
     assert_that(cargo_process("init").arg("--bin").arg("--vcs").arg("none")
                                     .env("USER", "foo").cwd(&path),
-                execs().with_status(0));
+                execs().with_status(0).with_stderr("\
+[CREATED] binary (application) project
+"));
 
     assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
     assert_that(&paths::root().join("foo/src/main.rs"), existing_file());
@@ -165,7 +169,7 @@ fn multibin_project_name_clash() {
         }
     "#).unwrap();
 
-    assert_that(cargo_process("init").arg("--vcs").arg("none")
+    assert_that(cargo_process("init").arg("--lib").arg("--vcs").arg("none")
                                     .env("USER", "foo").cwd(&path),
                 execs().with_status(101).with_stderr("\
 [ERROR] multiple possible binary sources found:
@@ -214,8 +218,10 @@ fn lib_already_exists_nosrc() {
 
 #[test]
 fn simple_git() {
-    assert_that(cargo_process("init").arg("--vcs").arg("git")
-                                    .env("USER", "foo"),
+    assert_that(cargo_process("init").arg("--lib")
+                                     .arg("--vcs")
+                                     .arg("git")
+                                     .env("USER", "foo"),
                 execs().with_status(0));
 
     assert_that(&paths::root().join("Cargo.toml"), existing_file());
@@ -229,7 +235,8 @@ fn auto_git() {
     let td = TempDir::new("cargo").unwrap();
     let foo = &td.path().join("foo");
     fs::create_dir_all(&foo).unwrap();
-    assert_that(cargo_process("init").cwd(foo.clone())
+    assert_that(cargo_process("init").arg("--lib")
+                                     .cwd(foo.clone())
                                      .env("USER", "foo"),
                 execs().with_status(0));
 
@@ -271,7 +278,7 @@ use --name to override crate name
 fn git_autodetect() {
     fs::create_dir(&paths::root().join(".git")).unwrap();
 
-    assert_that(cargo_process("init")
+    assert_that(cargo_process("init").arg("--lib")
                                     .env("USER", "foo"),
                 execs().with_status(0));
 
@@ -287,7 +294,7 @@ fn git_autodetect() {
 fn mercurial_autodetect() {
     fs::create_dir(&paths::root().join(".hg")).unwrap();
 
-    assert_that(cargo_process("init")
+    assert_that(cargo_process("init").arg("--lib")
                                     .env("USER", "foo"),
                 execs().with_status(0));
 
@@ -304,8 +311,8 @@ fn gitignore_appended_not_replaced() {
 
     File::create(&paths::root().join(".gitignore")).unwrap().write_all(b"qqqqqq\n").unwrap();
 
-    assert_that(cargo_process("init")
-                                    .env("USER", "foo"),
+    assert_that(cargo_process("init").arg("--lib")
+                                     .env("USER", "foo"),
                 execs().with_status(0));
 
 
@@ -323,7 +330,7 @@ fn gitignore_appended_not_replaced() {
 fn cargo_lock_gitignored_if_lib1() {
     fs::create_dir(&paths::root().join(".git")).unwrap();
 
-    assert_that(cargo_process("init").arg("--vcs").arg("git")
+    assert_that(cargo_process("init").arg("--lib").arg("--vcs").arg("git")
                                      .env("USER", "foo"),
                 execs().with_status(0));
 
index 23b637d3d1228e030c0eae44504f0868b1b20d97..e58a47188dd82327b08eee60ccc50479811d0113 100644 (file)
@@ -21,9 +21,11 @@ fn cargo_process(s: &str) -> ProcessBuilder {
 
 #[test]
 fn simple_lib() {
-    assert_that(cargo_process("new").arg("foo").arg("--vcs").arg("none")
+    assert_that(cargo_process("new").arg("--lib").arg("foo").arg("--vcs").arg("none")
                                     .env("USER", "foo"),
-                execs().with_status(0));
+                execs().with_status(0).with_stderr("\
+[CREATED] library `foo` project
+"));
 
     assert_that(&paths::root().join("foo"), existing_dir());
     assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
@@ -36,9 +38,11 @@ fn simple_lib() {
 
 #[test]
 fn simple_bin() {
-    assert_that(cargo_process("new").arg("foo").arg("--bin")
+    assert_that(cargo_process("new").arg("--bin").arg("foo")
                                     .env("USER", "foo"),
-                execs().with_status(0));
+                execs().with_status(0).with_stderr("\
+[CREATED] binary (application) `foo` project
+"));
 
     assert_that(&paths::root().join("foo"), existing_dir());
     assert_that(&paths::root().join("foo/Cargo.toml"), existing_file());
@@ -54,7 +58,7 @@ fn simple_bin() {
 #[test]
 fn simple_git() {
     let td = TempDir::new("cargo").unwrap();
-    assert_that(cargo_process("new").arg("foo").cwd(td.path().clone())
+    assert_that(cargo_process("new").arg("--lib").arg("foo").cwd(td.path().clone())
                                     .env("USER", "foo"),
                 execs().with_status(0));
 
@@ -120,7 +124,7 @@ use --name to override crate name"));
 
 #[test]
 fn rust_prefix_stripped() {
-    assert_that(cargo_process("new").arg("rust-foo").env("USER", "foo"),
+    assert_that(cargo_process("new").arg("--lib").arg("rust-foo").env("USER", "foo"),
                 execs().with_status(0)
                        .with_stdout("note: package will be named `foo`; use --name to override"));
     let toml = paths::root().join("rust-foo/Cargo.toml");
index 52799073595b6853cf69999bc6055c27d3a61612..3fad3b57ffac0fe4d6b89c38685fd504e96fabc0 100644 (file)
@@ -768,7 +768,7 @@ fn new_warns_you_this_will_not_work() {
         .file("src/lib.rs", "");
     p.build();
 
-    assert_that(p.cargo("new").arg("bar").env("USER", "foo"),
+    assert_that(p.cargo("new").arg("--lib").arg("bar").env("USER", "foo"),
                 execs().with_status(0)
                        .with_stderr("\
 warning: compiling this new crate may not work due to invalid workspace \
@@ -780,6 +780,7 @@ workspace: [..]
 
 this may be fixable by ensuring that this crate is depended on by the workspace \
 root: [..]
+[CREATED] library `bar` project
 "));
 }